import os
import queue
import logging
import tkinter as tk
from tkinter import ttk, scrolledtext, messagebox
import threading
import schedule
import time
import configparser
from datetime import datetime
import subprocess

# 日志配置
logging.basicConfig(filename='restart_errors.log', level=logging.ERROR,
                    format='%(asctime)s - %(levelname)s - 错误信息: %(message)s')


class SQLServerServiceRestartApp:
	def __init__(self, root):
		self.root = root
		self.root.title("SQL Server 服务定时重启工具_MrCui")
		self.root.geometry("400x350")
		# 窗体第一次出现的位置 在屏幕的中间
		self.root.update_idletasks()
		x = (self.root.winfo_screenwidth() - self.root.winfo_reqwidth()) / 2
		y = (self.root.winfo_screenheight() - self.root.winfo_reqheight()) / 2
		self.root.geometry("+%d+%d" % (x, y))
		# 配置文件设置
		self.config_file = r"C:\SQLServerRestartConfig.txt"
		self.check_config_file()
		
		# 初始化样式
		self.style = ttk.Style()
		self.style.theme_use('clam')
		
		# 任务控制
		self.scheduler_running = False
		self.schedule_thread = None
		self.log_queue = queue.Queue()
		
		# 创建界面组件
		self.create_widgets()
		
		# 加载配置
		self.load_config()
		
		# 启动日志处理
		self.root.after(100, self.process_log_queue)
	
	def check_config_file(self):
		"""检查并创建配置文件"""
		try:
			if not os.path.exists(self.config_file):
				with open(self.config_file, 'w', encoding='utf-8') as f:
					f.write("[DEFAULT]\n")
				self.log("配置文件已创建于C盘根目录")
		except PermissionError:
			messagebox.showerror("权限错误", "无法在C盘创建配置文件，请以管理员身份运行")
			self.root.destroy()
		except Exception as e:
			messagebox.showerror("配置错误", f"配置文件初始化失败: {str(e)}")
			self.root.destroy()
	
	def create_widgets(self):
		"""创建界面组件"""
		main_frame = ttk.Frame(self.root, padding=10)
		main_frame.pack(fill=tk.BOTH, expand=True)
		
		# 定时配置
		schedule_frame = ttk.LabelFrame(main_frame, text="定时配置", padding=10)
		schedule_frame.grid(row=0, column=0, padx=5, pady=5, sticky=tk.W + tk.E)
		
		ttk.Label(schedule_frame, text="执行频率:").grid(row=0, column=0, sticky=tk.W)
		self.frequency = ttk.Combobox(schedule_frame, values=["每天", "每小时"], width=10)
		self.frequency.grid(row=0, column=1, padx=5, pady=2)
		self.frequency.set("每天")
		
		ttk.Label(schedule_frame, text="执行时间:").grid(row=0, column=2, sticky=tk.W)
		self.schedule_time = ttk.Entry(schedule_frame, width=10)
		self.schedule_time.grid(row=0, column=3, padx=5, pady=2)
		self.schedule_time.insert(0, "00:00")
		
		# 控制按钮
		btn_frame = ttk.Frame(main_frame)
		btn_frame.grid(row=1, column=0, pady=10)
		
		self.start_btn = ttk.Button(btn_frame, text="开始定时重启", command=self.start_restart)
		self.start_btn.pack(side=tk.LEFT, padx=5)
		
		self.stop_btn = ttk.Button(btn_frame, text="停止定时重启", command=self.stop_restart, state=tk.DISABLED)
		self.stop_btn.pack(side=tk.LEFT, padx=5)
		
		# 日志区域
		log_frame = ttk.LabelFrame(main_frame, text="操作日志", padding=10)
		log_frame.grid(row=2, column=0, padx=5, pady=5, sticky=tk.W + tk.E + tk.N + tk.S)
		
		self.log_text = scrolledtext.ScrolledText(log_frame, width=40, height=10)
		self.log_text.pack(fill=tk.BOTH, expand=True)
		
		# 配置标签颜色
		self.log_text.tag_config('error', foreground='red')
		self.log_text.tag_config('info', foreground='blue')
	
	def restart_sql_server_service(self):
		"""重启 SQL Server 服务"""
		try:
			# 使用 subprocess 模块停止服务
			subprocess.run('net stop MSSQLSERVER', shell=True, check=True)
			time.sleep(5)
			# 使用 subprocess 模块启动服务
			subprocess.run('net start MSSQLSERVER', shell=True, check=True)
			self.log("SQL Server 服务已成功重启")
			# messagebox.showinfo("成功", "SQL Server 服务已成功重启！")
		except subprocess.CalledProcessError as e:
			self.log(f"重启失败：{str(e)}", error=True)
			logging.error(str(e))
			messagebox.showerror("错误", f"重启失败：{str(e)}")
	
	def start_restart(self):
		"""启动定时重启任务"""
		frequency = self.frequency.get()
		self.schedule_job(frequency)
		self.toggle_controls(False)
		self.start_scheduler()
	
	def schedule_job(self, frequency):
		"""设置定时任务"""
		schedule.clear()
		time_str = self.schedule_time.get()
		
		try:
			if frequency == "每天":
				schedule.every().day.at(time_str).do(self.restart_sql_server_service)
			elif frequency == "每小时":
				schedule.every().hour.at(time_str.split(':')[1]).do(self.restart_sql_server_service)
			self.log(f"定时任务已设置：{frequency} {time_str}")
		except Exception as e:
			self.log(f"定时设置失败：{str(e)}", error=True)
			messagebox.showerror("错误", f"时间格式错误：{str(e)}")
	
	def start_scheduler(self):
		"""启动定时器"""
		self.scheduler_running = True
		
		def run_scheduler():
			while self.scheduler_running:
				schedule.run_pending()
				time.sleep(1)
		
		threading.Thread(target=run_scheduler, daemon=True).start()
	
	def stop_restart(self):
		"""停止定时重启任务"""
		self.scheduler_running = False
		schedule.clear()
		self.toggle_controls(True)
		self.log("定时重启任务已停止")
	
	def toggle_controls(self, enabled):
		"""切换控件状态"""
		state = tk.NORMAL if enabled else tk.DISABLED
		self.start_btn.config(state=state)
		self.stop_btn.config(state=tk.DISABLED if enabled else tk.NORMAL)
	
	def log(self, message, error=False):
		"""记录日志"""
		timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
		log_msg = f"[{timestamp}] {message}"
		self.log_queue.put((log_msg, error))
	
	def process_log_queue(self):
		"""处理日志队列"""
		try:
			while True:
				msg, error = self.log_queue.get_nowait()
				tag = "error" if error else "info"
				self.log_text.insert(tk.END, msg + "\n", tag)
				self.log_text.see(tk.END)
		except queue.Empty:
			pass
		self.root.after(100, self.process_log_queue)
	
	def load_config(self):
		"""加载配置文件"""
		config = configparser.ConfigParser()
		try:
			config.read(self.config_file, encoding='utf-8')
			
			# 定时配置
			self.frequency.set(config.get('SCHEDULE', 'Frequency', fallback='每天'))
			self.schedule_time.delete(0, tk.END)
			self.schedule_time.insert(0, config.get('SCHEDULE', 'Time', fallback='00:00'))
		
		except Exception as e:
			messagebox.showwarning("配置加载警告", f"配置文件读取错误: {str(e)}")
	
	def save_config(self):
		"""保存配置文件"""
		config = configparser.ConfigParser()
		
		try:
			config['SCHEDULE'] = {
				'Frequency': self.frequency.get(),
				'Time': self.schedule_time.get()
			}
			
			with open(self.config_file, 'w', encoding='utf-8') as f:
				config.write(f)
		
		except Exception as e:
			messagebox.showerror("配置错误", f"配置文件保存失败: {str(e)}")
	
	def on_closing(self):
		"""关闭窗口事件处理"""
		self.save_config()
		self.stop_restart()
		self.root.destroy()


if __name__ == "__main__":
	root = tk.Tk()
	app = SQLServerServiceRestartApp(root)
	root.protocol("WM_DELETE_WINDOW", app.on_closing)
	root.mainloop()
